package attendance;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

public class Outputer {
    private Workbook book;
    private int oldSheetNumber;
    private String fileName;
    private Map<String, Sheet> sheetMap;
    
    private static final int HEADER_ROW = 4;

    public Outputer(String fileName, String templateFileName) throws FileNotFoundException, IOException {
        this.fileName = fileName;
        
        sheetMap = new HashMap<String, Sheet>();
        book = new HSSFWorkbook(new FileInputStream(templateFileName));
        book.setForceFormulaRecalculation(true);
        oldSheetNumber = book.getNumberOfSheets();
    }

    public void output(List<Staff> staffList) throws FileNotFoundException, IOException {
        CreationHelper factory = book.getCreationHelper();
        
        Sheet sheet = null;
        int staffIndex = 0;
        Cell morningCell = null, afternoonCell = null;
        Map<String, Integer> staffIndexMap = new HashMap<String, Integer>();
        for (Staff staff : staffList) {
            if (sheetMap.containsKey(staff.getGroup())) {
                sheet = sheetMap.get(staff.getGroup());
                staffIndex = staffIndexMap.get(staff.getGroup());
            } else {
                sheet = book.cloneSheet(0);
                int sheetIndex = book.getSheetIndex(sheet);
                book.setSheetName(sheetIndex, staff.getGroup());
                sheetMap.put(staff.getGroup(), sheet);
                
                staffIndex = 0;
            }
            Drawing drawing = sheet.createDrawingPatriarch();
            
            // set month
            if (staffIndex == 0) {
                Row dateRow = sheet.getRow(0);
                for (Attendance attendance : staff.getAttendanceList()) {
                    if (attendance.getDate() == null) {
                        continue;
                    }
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(attendance.getDate());
                    int month = calendar.get(Calendar.MONTH) + 1;
                    Cell dateCell = dateRow.getCell(6);
                    dateCell.setCellValue(month);
                }
            }
            Row morningRow = sheet.getRow(staffIndex * 2 + HEADER_ROW);
            Row afternoonRow = sheet.getRow(staffIndex * 2 + HEADER_ROW + 1);

            // set name
            morningCell = morningRow.getCell(0);
            morningCell.setCellValue(staff.getName());
           
            
            for (Attendance attendance : staff.getAttendanceList()) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(attendance.getDate());
                int columnNum = calendar.get(Calendar.DAY_OF_MONTH) + 1;
                morningCell = morningRow.getCell(columnNum);
                afternoonCell = afternoonRow.getCell(columnNum);
                if (attendance.getAbsentDay() > 0) {
                    morningCell.setCellValue("×");
                    afternoonCell.setCellValue("×");
                } else {
                    if (attendance.getLateMinute() > 0) {
                        morningCell.setCellValue("※");
                        ClientAnchor anchor = factory.createClientAnchor();
                        anchor.setCol1(morningCell.getColumnIndex());
                        anchor.setCol2(morningCell.getColumnIndex() + 5);
                        anchor.setRow1(morningRow.getRowNum());
                        anchor.setRow2(morningRow.getRowNum() + 2);
                        Comment comment = drawing.createCellComment(anchor);
                        RichTextString str = factory
                                .createRichTextString(String.format("迟到%.0f分钟",
                                        attendance.getLateMinute()));
                        comment.setString(str);
                        morningCell.setCellComment(comment);
                    } else if (attendance.getArriveNote() == null || 
                            (!attendance.getArriveNote().equals("休息") && !attendance.getArriveNote().equals("未刷卡"))
                        ) {
                        morningCell.setCellValue("√");
                    }
                    if (attendance.getEarlyMinute() > 0) {
                        afternoonCell.setCellValue("◇");
                        ClientAnchor anchor = factory.createClientAnchor();
                        anchor.setCol1(afternoonCell.getColumnIndex());
                        anchor.setCol2(afternoonCell.getColumnIndex() + 5);
                        anchor.setRow1(afternoonRow.getRowNum());
                        anchor.setRow2(afternoonRow.getRowNum() + 2);
                        Comment comment = drawing.createCellComment(anchor);
                        RichTextString str = factory
                                .createRichTextString(String.format("早退%.0f分钟",
                                        attendance.getEarlyMinute()));
                        comment.setString(str);
                        afternoonCell.setCellComment(comment);
                    } else if (attendance.getLeaveNote() == null || 
                            (!attendance.getLeaveNote().equals("休息") && !attendance.getLeaveNote().equals("未刷卡"))
                        ){
                        afternoonCell.setCellValue("√");
                    }
                }
            }
            staffIndex++;
            staffIndexMap.put(staff.getGroup(), staffIndex);
        }

        // delete old sheet
        for (int i = 0; i < oldSheetNumber; i++) {
            book.removeSheetAt(0);
        }
        
        book.write(new FileOutputStream(fileName));
    }
    
}
